import { findPara, findCode } from '../find';
import { record } from '../revoke/record';
import hljs from '../highlight/index';

let root;
let selection, range;

function syncHeight() {
  window.parent.postMessage(JSON.stringify({
    type: 'changeRTFHeight',
    height: root.scrollHeight
  }))
}

function setRoot(a){
  if(typeof a === 'string') root = document.querySelector(a);
  else if(a instanceof Node) root = a;
  else {
    console.error(`paste handler set root: root-${root} is not a string or node`);
  }
}

function pasteHandler(event){
  event.preventDefault();

  record();

  selection = window.getSelection();
  if(!selection.rangeCount) return;
  range = selection.getRangeAt(0);

  range = window.getSelection().getRangeAt(0);
  let startPara = findPara(range.startContainer);
  let endPara = findPara(range.endContainer);

  const paraTagName = startPara.tagName;

  let data = event.clipboardData.getData('text');
  let texts = data.split(/\r?\n/).reverse();

  if(texts.length === 0) {
  }
  else if (texts.length === 1) {
    range.extractContents();
    let newTextNode = document.createTextNode(texts[0]);
    startPara.appendChild(newTextNode);

    let codeBlock = findCode(startPara);
    if(codeBlock) {
      startPara.innerHTML = hljs.highlight(startPara.innerText, {
        language: codeBlock.dataset.lang
      }).value;
    }

    range.selectNodeContents(newTextNode);
    range.collapse();
  }
  else {
    range.extractContents();
    if(startPara === endPara) {
      range.setEndAfter(startPara);
      range.insertNode(range.extractContents());
      endPara = startPara.nextSibling;
    }
    let firstLine = document.createTextNode(texts.pop());
    let lastLine = document.createTextNode(texts.shift());
    
    startPara.appendChild(firstLine);
    let codeBlock = findCode(startPara);
    if(codeBlock) {
      startPara.innerHTML = hljs.highlight(startPara.innerText, {
        language: codeBlock.dataset.lang
      }).value;
    }

    endPara.insertBefore(lastLine, endPara.firstChild);
    codeBlock = findCode(endPara);
    if(codeBlock) {
      endPara.innerHTML = hljs.highlight(endPara.innerText, {
        language: codeBlock.dataset.lang
      }).value;
    }

    codeBlock = findCode(startPara);
    texts.forEach(text => {
      let para = document.createElement(paraTagName);
      if(codeBlock) {
        para.innerHTML = hljs.highlight(text, {
          language: codeBlock.dataset.lang
        }).value;
      } else {
        para.innerText = text;
      }
      startPara.parentNode.insertBefore(para, startPara.nextSibling);
    })

    range.setStart(firstLine, 0);
    range.setEnd(lastLine, lastLine.length);
    range.collapse();
  }

  syncHeight();
}

export {
  setRoot,
  pasteHandler
};